home *** CD-ROM | disk | FTP | other *** search
- ----------
- X-Sun-Data-Type: text
- X-Sun-Data-Description: text
- X-Sun-Data-Name: text
- X-Sun-Content-Lines: 114
-
-
- > From root Thu Jul 15 20:00:27 1993
- > >From ramanand@thor.ece.uc.EDU Thu Jul 15 20:00:27 1993
- > Date: 15 Jul 93 13:57:27-0400
- > From: John Holmes Sr <ramanand@thor.ece.uc.EDU>
- > Subject: flex++/bison++
- > To: coetmeur@icdc.fr
- > MIME-version: 1.0
- > Content-Type> : > text/plain> ; > charset=US-ASCII>
- > Content-transfer-encoding: 7bit
- >
- > Hello Alain,
- >
- > I recently ported the flex++/bison++ software that you have put up on the
- > ftp server under comp.compilers.
- >
- > First of all I would like to complement you on a job well underakten. The
- > documentation is quite beneficial.
- >
- > However I have been having some problems with generating multiple parsers
- > in the same executable. It is quite possible that my understanding of the
- > full capabilities of the notions of class etc. are not quite up to the
- > mark. I would appreciate any help you can provide.
- >
- >
- > I have tried the following approach. If there is a better way, please let
- > me know.
- >
- >
- > Prepare two bison++ files. Each of them declares a different class
- > for the parser. Each of them declares its LEX_BODY as = 0 (i.e. a
- > pure virtual function). Prepare two flex++ files. Each of them
- > inherits the properties of the corresponding parser class and defines
- > the lexical analyser functions.
- >
- > So I now have two sets of header files.
- >
- > a. parser1.h and lex1.h
- > b. parser2.h and lex2.h
- >
- >
- >
- >
- > Each set of parser/lexical analyser individually compiles correctly
- > with the latest gnu c++ compiler. However, if I try to include both
- > the lexical header files (lex1.c and lex2.c) in the main file, I get syntax
- > errors. The reason is in the first two lines of these header files. They
- > are duplicated here below:
- >
- > #ifndef FLEX_HEADER_lex__h
- > #define FLEX_HEADER_lex__h
- > ...
- > ...
- >
- >
- > Since both these files define the same symbol FLEX_HEADER_lex__h,
- > obviously the second time that I include the header file, it is ignored
- > by the preprocessor.
- >
- > Can you give me some solutions to this. Either I could somehow rename this
- > symbol , or you have a better class hierarchy that I am unaware of
- > currently.
- >
-
-
-
- The way we can use multiple parser or scanner is by changing
- the name of the scanner/parser with the directive %name. it is
- ESSENTIAL. By default and for compatibility the name is set to 'lex'
- and 'parse', but it should be changed to a different name for each
- parser/scanner. Further, the scanner and parser must not have the
- same name. the name given is used as the class name, and to build
- many symbol names. So you should give a %name directive, before any
- other in the flex++ and bison++ files. If all the header use the
- symbol FLEX_HEADER_lex__h if shoul mean that they use the same
- %name. If it is not the case, it is a very important bug. I was not
- able to reproduce it with the data I have.
-
- The way to comunicate between the scanner and the parser is not
- a trivial choic, and at our site we discussed much about it. The
- problems are complex since the scanner use parser constant for token
- ID, the parser use the scanner function as token furnisher, and so
- on...
-
- The way that we used is to create a derived class from the
- parser class, containing the scanner itself, and redefining the
- token reader function of the parser to call the scanner function of
- the scanner. It seems good for many reasons:
-
- - the compiler (ie parser+scanner) IS essentially a PARSER,
- that USE a particular SCANNER to give tokens.
-
- - the intermediate function that give tokens from the
- scanner to the parser is a good place to put trace, and
- management function (line count...)
-
- The design was so important to explain to new users in our
- site, that I decided to build a template of compiler that is a
- base to modify. It should be present in misc++, but I send it as
- attachment (4 files).
-
- I am concient that the documentation I have given is very
- technical, and assume a deep knowledge of flex, bison, C/C++, and
- some design experiences.
-
-
- Please tell me was is the result of your new try, successful or not.
-
- Hoping I could help you, Best regard.
-
-
- Alain Coetmeur
-
-
- ----------
- X-Sun-Data-Type: rdti-source-makefile
- X-Sun-Data-Name: makefile
- X-Sun-Content-Lines: 28
-
-
-
- .SUFFIXES : .cc .y .l $(SUFFIXES)
-
- .cc.o :
- CC -I$(CENTERCCLIBDIR)/incl -c $*.cc
-
- .y.cc :
- bison++ -d -o $*.cc -h $*.h $*.y
- .l.cc :
- flex++ -h$*.h -o$*.cc $*.l
- .y.h :
- bison++ -d -o $*.cc -h $*.h $*.y
- .l.h :
- flex++ -h$*.h -o$*.cc $*.l
-
- all : compiler
-
- MyCompiler.o : MyCompiler.cc MyParser.h MyScanner.h
-
- MyParser.o : MyParser.cc MyParser.h
-
- MyScanner.o : MyScanner.cc MyScanner.h MyParser.h
-
-
- compiler : MyCompiler.o MyParser.o MyScanner.o
- CC -o $@ MyCompiler.o MyParser.o MyScanner.o
-
- ----------
- X-Sun-Data-Type: rdtq-source-l
- X-Sun-Data-Name: MyScanner.l
- X-Sun-Content-Lines: 42
-
- /* %Z% %M% %Y% %Q% %I% %E% %U% (%F%) */
- /*
- * Nom du Fichier : |>nom_fichier<|
- * Titre : |>Titre<|
- * Auteur: |>auteur<|
- * Date de creation : |>dateCreation<|
- */
- /* Description :
- * Document de reference : |>doc<|
- * Objet : |>objet<|
- *
- */
- /*
- * historique :
- * |>date<| |>auteur<| |>objet<|
- */
- /* -------------- declaration section -------------- */
- %name MyScanner
-
- %define LEX_PARAM YY_MyParser_STYPE *val,YY_MyParser_LTYPE *loc
- %define MEMBERS public: int theLine,theColumn;
- %define CONSTRUCTOR_INIT : theLine(1),theColumn(1)
- %header{
- #include "MyParser.h"
- %}
-
- %{
- static char SccsId[]="%Z% %M% %Y% %Q% %I% %E% %U% (%F%)";
- %}
-
- /* -------------- rules section -------------- */
- SPACES [ \t]+
- %%
- "\n" {val->ctype='\n';
- theLine++;theColumn=1;
- return MyParser::EOL_TOKEN; }
- . {
- val->ctype=yytext[0];
- theColumn++;
- return MyParser::CHAR_TOKEN; }
- <<EOF>> { yyterminate();}
- %%
- ----------
- X-Sun-Data-Type: rdtq-source-y
- X-Sun-Data-Name: MyParser.y
- X-Sun-Content-Lines: 50
-
- /* %Z% %M% %Y% %Q% %I% %E% %U% (%F%) */
- /*
- * Nom du Fichier : |>nom_fichier<|
- * Titre : |>Titre<|
- * Auteur: |>auteur<|
- * Date de creation : |>dateCreation<|
- */
- /* Description :
- * Document de reference : |>doc<|
- * Objet : |>objet<|
- *
- */
- /*
- * historique :
- * |>date<| |>auteur<| |>objet<|
- */
- /* -------------- declaration section -------------- */
-
- %name MyParser
- %define LSP_NEEDED
- %define ERROR_BODY =0
- %define LEX_BODY =0
- %header{
- #include <stdio.h>
- %}
-
- %union {
- int itype; /* for count */
- char ctype; /* for char */
- }
- %token <ctype> EOL_TOKEN CHAR_TOKEN
- %type <itype> file line lines chars
- %start file
-
- /* -------------- rules section -------------- */
- /* Sample parser. Does count Chars in a line, and lines in file */
- %%
- file : lines
- {printf("nlines=%d\n",$1); /* show line count */}
- ;
- lines : line {$$=1; /* first line of all */}
- | lines line {$$=$1+1; /* count one more line */}
- ;
- line : chars EOL_TOKEN {$$=$1;printf("nchars=%d\n",$1); /* show char count */}
- ;
- chars : CHAR_TOKEN { $$=1;/* first char of line */}
- | chars CHAR_TOKEN {$$=$1+1; /* count one more char */}
- ;
- %%
- /* -------------- body section -------------- */
- ----------
- X-Sun-Data-Type: rdtq-source-cc
- X-Sun-Data-Name: MyCompiler.cc
- X-Sun-Content-Lines: 52
-
- static char SccsId[]="%Z% %M% %Y% %Q% %I% %E% %U% (%F%)";
- //
- // Nom du Fichier : |>nom_fichier<|
- // Titre : |>Titre<|
- // Auteur: |>auteur<|
- // Date de creation : |>dateCreation<|
- //
- // Description :
- // Document de reference : |>doc<|
- // Objet : |>objet<|
- //
- //
- //
- // historique :
- // |>date<| |>auteur<| |>objet<|
- //
- #include "MyScanner.h"
- #include "MyParser.h"
-
- class MyCompiler : public MyParser
- {private:
- MyScanner theScanner;
- public:
- virtual int yylex();
- virtual void yyerror(char *m);
- MyCompiler()
- {};
- };
-
- int MyCompiler::yylex()
- {
- yylloc.first_line=theScanner.theLine;
- yylloc.first_column=theScanner.theColumn;
- int token=theScanner.yylex(&yylval,&yylloc);
- yylloc.last_line=theScanner.theLine;
- yylloc.last_column=theScanner.theColumn;
- yylloc.text=(char *)theScanner.yytext;
- return token;
- }
-
- void MyCompiler::yyerror(char *m)
- { fprintf(stderr,"%d: %s at token '%s'\n",yylloc.first_line, m,yylloc.text);
- }
-
- int main(int argc,char **argv)
- {
- MyCompiler aCompiler;
- int result=aCompiler.yyparse();
- printf("Resultat Parsing=%s\n",result?"Erreur":"OK");
- return 0;
- };
-
-
-